/**
 * Copyright @ 2013 - 2015 Suntec Software(Shanghai) Co., Ltd.
 * All Rights Reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are NOT permitted except as agreed by
 * Suntec Software(Shanghai) Co., Ltd.
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 */

/**
 * @file ViewLoadHelper.h
 * @brief Declaration and implement of class CustomQmlFileLoader.
 *
 * This file includes the declaration and implement of class CustomQmlFileLoader, and
 * the definitions of the macros.
 *
 * @attention used for C++ only.
 */

#ifndef VIEWLOADHELPER_H
#define VIEWLOADHELPER_H

#ifndef __cplusplus
#    error ERROR: This file requires C++ compilation (use a .cpp suffix)
#endif

#include "ngbase/NGLog.h"
#include "qmlframework/NQQmlFileLoader.h"
#include "qmlframework/NQViewBase.h"
#include <QtQml>

#ifndef APPNAME
#define APPNAME(name) { \
    if (CustomQmlFileLoader::createInstance()) { \
    CustomQmlFileLoader::createInstance()->addAppName(name); \
    } }
#endif /* APPNAME */

#ifndef VIEWPREFIX
#define VIEWPREFIX(prefix) { \
    if (CustomQmlFileLoader::createInstance()) { \
    CustomQmlFileLoader::createInstance()->addViewPrefix(prefix); \
    } }
#endif /* VIEWPREFIX */

#ifndef MAINSCREENPREFIX
#define MAINSCREENPREFIX(prefix) { \
    if (CustomQmlFileLoader::createInstance()) { \
    CustomQmlFileLoader::createInstance()->addMainScreenPrefix(prefix); \
    } }
#endif /* MAINSCREENPREFIX */

#ifndef SIDESCREENPREFIX
#define SIDESCREENPREFIX(prefix) { \
    if (CustomQmlFileLoader::createInstance()) { \
    CustomQmlFileLoader::createInstance()->addSideScreenPrefix(prefix); \
    } }
#endif /* SIDESCREENPREFIX */

#ifndef LAYERITEMPREFIX
#define LAYERITEMPREFIX(prefix) { \
    if (CustomQmlFileLoader::createInstance()) { \
    CustomQmlFileLoader::createInstance()->addLayerItemPrefix(prefix); \
    } }
#endif /* LAYERITEMPREFIX */

#ifndef ONSPREFIX
#define ONSPREFIX(prefix) { \
    if (CustomQmlFileLoader::createInstance()) { \
    CustomQmlFileLoader::createInstance()->addONSPrefix(prefix); \
    } }
#endif /* ONSPREFIX */

/**
 * @brief class CustomQmlFileLoader.
 *
 * This class is to load the custom qml files.
 */
class CustomQmlFileLoader : public NQQmlFileLoaderHelper
{
public:
    /// constructor.
    CustomQmlFileLoader(AppId appId)
        : NQQmlFileLoaderHelper(appId)
    {
    }

    /// destructor.
    ~CustomQmlFileLoader() {}

    /// overriden from class NQQmlFileLoaderHelper, a pure virtual funcion to load qml state.
    virtual QQuickItem* loadState(QQmlEngine *engine, const QString &url, QQmlContext *ctx);

    /// overriden from class NQQmlFileLoaderHelper, a pure virtual funcion to load qml view.
    virtual NQViewBase* loadView(QQmlEngine *engine, const QString &url, QQmlContext *ctx);
    /// sigleton of class CustomQmlFileLoader creation.
    static CustomQmlFileLoader* createInstance(AppId appId = InvalidAppId);

private:
    /// for sigleton.
    static CustomQmlFileLoader *m_self;
};

CustomQmlFileLoader* CustomQmlFileLoader::m_self = NULL;
CustomQmlFileLoader* CustomQmlFileLoader::createInstance(AppId appId)
{
    if (NULL == m_self) {
        m_self = new CustomQmlFileLoader(appId);
    }
    return m_self;
}

QQuickItem* CustomQmlFileLoader::loadState(QQmlEngine *engine, const QString &url, QQmlContext* ctx)
{
    QQmlComponent component(engine, QUrl(url));
    if (component.status() == QQmlComponent::Ready) {
        QQuickItem *item = qobject_cast<QQuickItem*>(component.create(ctx));
        if (item) {
            NGLogDebug("QmlFramework", "CustomQmlFileManager::loadStates success, QUrl : %s!", url.toStdString().c_str());
            return item;
        }
        else {
            NGLogDebug("QmlFramework", "CustomQmlFileManager::loadStates failed, QUrl : %s!", url.toStdString().c_str());
        }
    }
    else {
        NGLogDebug("QmlFramework", "CustomQmlFileManager::loadStates failed, QmlEngine : %d!", engine);
        NGLogDebug("QmlFramework", "CustomQmlFileManager::loadStates failed, erro : %s!", component.errorString().toStdString().c_str());
    }
    return NULL;
}

NQViewBase* CustomQmlFileLoader::loadView(QQmlEngine *engine, const QString& url, QQmlContext* ctx)
{
    QQmlComponent component(engine, QUrl(url));
    NQViewBase *childItem = qobject_cast<NQViewBase*>(component.create(ctx));
    if (NULL == childItem) {
        NGLogDebug("QmlFramework", "CustomQmlFileManager::loadQmlView failed, QmlEngine : %d!", engine);
        NGLogDebug("QmlFramework", "CustomQmlFileManager::loadQmlView failed, QUrl : %s!", url.toStdString().c_str());
        NGLogDebug("QmlFramework", "CustomQmlFileManager::loadQmlView failed, erro : %s!", component.errorString().toStdString().c_str());
    }
    else {
        NGLogDebug("QmlFramework", "CustomQmlFileManager::loadQmlView succeeded!");
    }
    return childItem;
}

#endif /* VIEWLOADHELPER_H */
/* EOF */

